#pragma once
#include "Thread.hpp"
#include "log.hpp"
#include <iostream>
#include <queue>
#include <vector>
#include "Mutex.hpp"
#include "cond.hpp"
namespace Threadpoolmodule
{
    using namespace Mutexmodule;
    using namespace Threadmodule;
    using namespace LogModule;
    using namespace Condmodule;

    template <class t>
    class Threadpool
    {
        static const int gnum = 5;

    private:
        int _num;
        std::vector<Thread> _threadpool;
        std::queue<t> _taskq;
        Cond _cond;
        Mutex _mutex;
        static Mutex _lock;
        bool _isrunning;
        int _sleepernum;
        //static Threadpool<t> *inc; // 单例指针
        Threadpool(int num = gnum) : _num(num), _isrunning(false), _sleepernum(0)
        {
            for (int i = 0; i < _num; i++)
            {
                _threadpool.emplace_back(
                    [this]()
                    {
                        handlertask(); // 或者写成Thread([this](){ handlertask(); })
                    });
            }
        }
        Threadpool(const Threadpool<t> &) = delete;
        Threadpool<t> &operator=(const Threadpool<t> &) = delete;
        ~Threadpool()
        {
        }

    public:
        static Threadpool<t> *getinstance(int num = gnum)
        {
            //第一种写法
            // if (inc == nullptr)
            // {
            //     Lockguard lg(_lock);
            //     if (inc == nullptr)
            //     {
            //         inc = new Threadpool<t>(num);
            //         LOG(Loglevel::DEBUG) << "首次创建单例" << "\r\n";
            //     }
            // }
            //return inc;
            //另一种写法
            static Threadpool<t> inc(num);//局部变量的初始化是线程安全的。这里更推荐第二种写法
            return &inc;
        }
        void handlertask()
        {
            char name[100];
            snprintf(name, 100, "thread-%d", (int)pthread_self());
            LOG(Loglevel::INFO) << name << " started" << "\r\n"; // ← 打印在线程刚启动时
            t task;
            while (true)
            {
                {
                    Lockguard lockguard(_mutex);
                    while (_taskq.empty() && _isrunning)
                    {
                        _sleepernum++;
                        _cond.wait(_mutex);
                        _sleepernum--;
                    }
                    if (!_isrunning && _taskq.empty())
                    {
                        LOG(Loglevel::INFO) << name << "退出" << "\r\n";
                        break;
                    }
                    task = _taskq.front();
                    _taskq.pop();
                }
                task(); // 处理任务，不要在临界区
            }
        }

        void start()
        {
            if (_isrunning)
                return;
            _isrunning = true;
            for (auto &thread : _threadpool)
                thread.start();
        }
        void Stop()
        {
            if (_isrunning == false)
                return;
            _isrunning = false;
            // 唤醒所有的线程
            wake_all_thread();
        }
        void wake_all_thread()
        {
            Lockguard lg(_mutex);
            if (_sleepernum > 0)
                _cond.broadcast();
            LOG(Loglevel::INFO) << "唤醒所有线程" << "\r\n";
        }
        void wake_one_thread()
        {
            _cond.signal();
            LOG(Loglevel::INFO) << "唤醒一个线程" << "\r\n";
        }
        void join()
        {
            for (int i = 0; i < _num; i++)
                _threadpool[i].join();
        }
        bool equeue(const t &task)
        {
            if (_isrunning)
            {
                Lockguard lg(_mutex);
                _taskq.push(task);
                if (_threadpool.size() - _sleepernum == 0) // 所有线程都在休眠
                    wake_one_thread();
                return true;
            }
            return false;
        }

    };
    //template <class t>
   // Threadpool<t> *Threadpool<t>::inc = nullptr; // static成员必须在类外初始化
    template <class t>
    Mutex Threadpool<t>::_lock; // 初始化，自动调用构造函数
}